package beastick.utility;

//Copyright 2008 Tofig Kareemov, estereos@gmail.com
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class CSimpleXML extends CUtilityMethods
{
 static DocumentBuilderFactory oDocBuilderFactory = DocumentBuilderFactory
                                                    .newInstance();
 private NodeList              oCurrentNodeList   = null;
 private Node                  oCurrentNode       = null;
 private CFileTools            oFileTools         = new CFileTools();
 private Document              oDoc               = null;

 static public String Encoded(String sIn)
 {
  StringBuffer sOut = new StringBuffer("");
  char sChar = ' ';
  for (int i = 0; i < sIn.length(); ++i)
  {
   sChar = sIn.charAt(i);
   if ((sChar == '<') || (sChar == '>') || (sChar == '&') || (sChar == '\r')
     || (sChar == '\n') || (sChar == '\t') || (sChar == '\"'))
   {
    sOut.append("&#x");
    if (sChar < 0x10)
    {
     sOut.append("0");
    }
    sOut.append(Integer.toHexString(sChar).toUpperCase());
    sOut.append(";");
   } else
   {
    sOut.append(sChar);
   }
  }
  return sOut.toString();
 }

 public Node GetXMLRootNodeNewCreated(String sRootNode)
 {
  Node oResult = null;
  try
  {
   DocumentBuilder oDocBuilder = oDocBuilderFactory.newDocumentBuilder();
   Node oNode = null;
   oDoc = oDocBuilder.newDocument();
   oNode = oDoc.createElement(sRootNode);
   oDoc.appendChild(oNode);
   oResult = oDoc.getFirstChild();
   oCurrentNodeList = oResult.getChildNodes();
   oCurrentNode = oResult;
  } catch (Throwable T)
  {
  }
  return oResult;
 };

 public Node GetXMLRootNodeLoaded(String sFileName, boolean bSilently)
 {
  Node oResult = null;
  try
  {
   DocumentBuilder oDocBuilder = oDocBuilderFactory.newDocumentBuilder();
   String sFile = oFileTools.FindFile(sFileName);
   if (!"".equals(sFile))
   {
    File f = new File(sFile);
    oDoc = oDocBuilder.parse(f);
   } else
   {
    sFile = oFileTools.FindResource(sFileName);
    if ("".equals(sFile))
    {
     throw new FileNotFoundException("could not find the file " + sFileName);
    }
    oDoc = oDocBuilder.parse(Thread.currentThread().getContextClassLoader()
      .getResourceAsStream(sFileName));
   }
   oResult = oDoc.getFirstChild();
   oCurrentNodeList = oResult.getChildNodes();
   oCurrentNode = oResult;
  } catch (Throwable T)
  {
   if (!bSilently)
   {
    T.printStackTrace();
    System.err.println("Problem in XML File: " + sFileName);
    System.out.println("Problem in XML File: " + sFileName);
   }
  }
  return oResult;
 };

 public Node GetXMLRootNodeLoadedFromXMLString(String sXML, boolean bSilently)
 {
  Node oResult = null;
  try
  {
   DocumentBuilder oDocBuilder = oDocBuilderFactory.newDocumentBuilder();
   oDoc = oDocBuilder.parse(new ByteArrayInputStream(sXML.getBytes()));
   oResult = oDoc.getFirstChild();
   oCurrentNodeList = oResult.getChildNodes();
   oCurrentNode = oResult;
  } catch (Throwable T)
  {
   if (!bSilently)
   {
    T.printStackTrace();
    System.err.println("Problem in XML File: " + "XML_String");
    System.out.println("Problem in XML File: " + "XML_String");
   }
  }
  return oResult;
 };

 public Node GetXMLChildNode(Node oNode, String sName, int iNumber)
 {
  Node oResult = null;
  if (oNode != null)
  {
   if (oNode.hasChildNodes())
   {
    if (!(oCurrentNode.equals(oNode)))
    {
     oCurrentNodeList = oNode.getChildNodes();
     oCurrentNode = oNode;
    }
    for (int i = 0; i < oCurrentNodeList.getLength(); i++)
    {
     if (oCurrentNodeList.item(i).getNodeName().trim().equalsIgnoreCase(
       sName.trim()))
     {
      --iNumber;
      if (iNumber <= 0)
      {
       oResult = oCurrentNodeList.item(i);
       i = oCurrentNodeList.getLength();
      }
     }
    }
   }
  }
  return oResult;
 };

 public Node GetXMLChildNodeByIndex(Node oNode, int iIndex)
 {
  Node oResult = null;
  if (oNode != null)
  {
   if (oNode.hasChildNodes())
   {
    if (!(oCurrentNode.equals(oNode)))
    {
     oCurrentNodeList = oNode.getChildNodes();
     oCurrentNode = oNode;
    }
    oCurrentNodeList.item(iIndex);
   }
  }
  return oResult;
 };

 public String GetXMLAttribValue(Node oNode, String sName)
 {
  String sResult = "";
  if (oNode != null)
  {
   if (oNode.hasAttributes())
   {
    NamedNodeMap oNodeList = oNode.getAttributes();
    for (int i = 0; i < oNodeList.getLength(); i++)
    {
     if (oNodeList.item(i).getNodeName().equals(sName))
     {
      sResult = oNodeList.item(i).getNodeValue();
     }
    }
   }
  }
  return sResult;
 };

 public Node GetXMLChildNodeByAttributeValue(Node oNode, String sName,
   String sAttributeName, String sAttributeValue)
 {
  Node oResult = null;
  if (oNode != null)
  {
   if (oNode.hasChildNodes())
   {
    if (!(oCurrentNode.equals(oNode)))
    {
     oCurrentNodeList = oNode.getChildNodes();
     oCurrentNode = oNode;
    }
    for (int i = 0; i < oCurrentNodeList.getLength(); i++)
    {
     if (oCurrentNodeList.item(i).getNodeName().trim().equalsIgnoreCase(
       sName.trim()))
     {
      if (GetXMLAttribValue(oCurrentNodeList.item(i), sAttributeName).equals(
        sAttributeValue))
      {
       oResult = oCurrentNodeList.item(i);
       i = oCurrentNodeList.getLength();
      }
     }
    }
   }
  }
  return oResult;
 };

 public Node CreateConfigurationParameterNode(String sName, String sValue)
 {
  Node oNodeAttrib = null;
  Node oNode = null;
  oNode = oDoc.createElement("param");
  if (IsValuable(sName))
  {
   oNodeAttrib = oDoc.createAttribute("name");
   oNodeAttrib.setNodeValue(sName);
   oNode.getAttributes().setNamedItem(oNodeAttrib);
   if (IsValuable(sValue))
   {
    oNodeAttrib = oDoc.createAttribute("value");
    oNodeAttrib.setNodeValue(sValue);
    oNode.getAttributes().setNamedItem(oNodeAttrib);
   }
  }
  return oNode;
 }

 public boolean WriteToFile(String sFilename)
 {
  boolean bResult = false;
  FileOutputStream oOutputStream = null;
  try
  {
   oFileTools.WriteTextToFile(sFilename, "");
   Source oSource = new DOMSource(oDoc);
   File oFile = new File(sFilename);
   oOutputStream = new FileOutputStream(oFile);
   Result oResult = new StreamResult(oOutputStream);
   Transformer oTransformer = TransformerFactory.newInstance().newTransformer();
   oTransformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
   oTransformer.transform(oSource, oResult);
   bResult = true;
  } catch (Throwable T)
  {
   return bResult;
  } finally
  {
   try
   {
    oOutputStream.close();
   } catch (Exception e)
   {
   }
  }
  return bResult;
 }

 public Document getDocument()
 {
  return oDoc;
 }
}